home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / t_os / wstype / source / txwind.c < prev    next >
C/C++ Source or Header  |  1991-10-18  |  15KB  |  616 lines

  1. /***   [txwind.c]
  2. *
  3. *    テキストウィンドウ 関連        (C)ささがわ
  4. *
  5. *    For GNU C Compiler (GCC)   Version 1.39
  6. *
  7. ***/
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <jctype.h>
  13. #include <mos.h>
  14. #include "graph.h"
  15. #include "icn.h"
  16. #include "window.h"
  17. #include "windmgr.h"
  18. #include "txwind.h"
  19. #include "others.h"
  20. #include "disp.h"
  21. #include "roll.h"
  22.  
  23. #define WH_CAN        0        /* キャンセル ボタン */
  24. #define WH_TITLE    1        /* タイトル */
  25. #define WH_SCVRW    2        /* 垂直スクロール後 */
  26. #define WH_SCVFF    3        /* 垂直スクロール前 */
  27. #define WH_SCHRW    4        /* 水平スクロール後 */
  28. #define WH_SCHFF    5        /* 水平スクロール前 */
  29. #define WH_BSCV        6        /* 垂直バー スクロール */
  30. #define WH_BSCH        7        /* 水平バー スクロール */
  31. #define WH_EXP        8        /* 拡大・縮小ボタン */
  32. #define WH_OPT1        9        /* 位置戻りオプション */
  33. #define WH_OPT2        10        /* 表示属性変更オプション */
  34. #define WH_MOJI        11        /* テキスト表示領域 */
  35. #define WH_OTHER    -1        /* その他 */
  36.  
  37. extern int    PAL_MOJI, PAL_Back, PAL_Black;
  38. static int    Xx1, Yy1, Xx2, Yy2, Wx, Wy;
  39. static int    Vw, Hw, Scspd = 2, Vg, Hg;
  40. static struct    txinfo_t    *Info;
  41.  
  42. static void    SUB_recall(void);
  43. static void    Winsize_change_sub(struct txinfo_t *, int);
  44. static void    SUB_move(int, int);
  45. static void    SUB_close(void);
  46. static int    Where(int, int);
  47. static void    SUB_enlarge(int, int);
  48. static void    Draw_window(char *, int, int, int, int);
  49. static void    SUB_scya(int);
  50. static int    SUB_scya_roll(int);
  51. static void    SUB_scya_bar(int);
  52. static void    Draw_scrollV(void);
  53. static void    Draw_scrollH(void);
  54. static void    SUB_scdr(int, int, int);
  55. static void    SUB_dragScroll(void);
  56. static void    SeigouV(void);
  57. static void    SeigouH(void);
  58. static int    SCROLL(int);
  59. static void    SUB_dispchange(void);
  60.  
  61. /* ウィンドウ・オープン m:1のとき文字のみ描画   wxx,wyy:スクリーン・オフセット */
  62. void TXW_open(int m, int wxx, int wyy) {
  63.     int        x1, y1, x2, y2;
  64.     char    str[80];
  65.     struct RECT        pl;
  66.     
  67.     /* グローバル変数セット */
  68.     Wx = wxx;    Wy = wyy;
  69.     Info = (struct txinfo_t *)WMGR_inf(-1);
  70.     WMGR_cord(-1, &pl);
  71.     Xx1 = pl.x1;    Yy1 = pl.y1;
  72.     Xx2 = pl.x2;    Yy2 = pl.y2;
  73.     
  74.     Vg = Info->fontx + Info->linegap;
  75.     Hg = Info->fontx / 2;
  76.     Vw = (Yy2 - Yy1 - 52 + Info->linegap) / Vg;
  77.     Hw = (Xx2 - Xx1 - 31) / Hg;
  78.     
  79.     if (!m) {
  80.         Cont_path(Info->name, (Xx2 - Xx1 - 122) / 8, str);
  81.         Draw_window(str, Xx1, Yy1, Xx2, Yy2);
  82.     }
  83.     
  84.     x1 = Xx1 + 8;
  85.     y1 = Yy1 + 29;
  86.     x2 = x1 + Hw * Hg - 1;
  87.     y2 = y1 + Vw * Vg - Info->linegap - 1;
  88.     ROL_init(Info, x1 - Wx, y1 - Wy, x2 - Wx, y2 - Wy);
  89.     MOS_disp(0);
  90.     EGB_boxf(x1, y1, x2, y2, 0, 0);
  91.     MOS_disp(1);
  92.     if (!m) {
  93.         Draw_scrollV();
  94.         Draw_scrollH();
  95.     }
  96. }
  97.  
  98. /* ウィンドウ・クローズ */
  99. void TXW_close(void) {
  100.     ROL_end(Wy, Xx1 + 8, Yy1 + 29);
  101. }
  102.  
  103. /* 番号指定ウィンドウ・オープン nw:ウィンドウNo. */
  104. void TXW_draw(int nw) {
  105.     int        i, pVw, pHw, pVg;
  106.     int        pxx1, pyy1, pxx2, pyy2;
  107.     unsigned char    str[80];
  108.     struct bmgr_t    bm;
  109.     struct txinfo_t    *pInfo;
  110.     struct RECT        c;
  111.     
  112.     pxx1 = Xx1;    pyy1 = Yy1;
  113.     pxx2 = Xx2;    pyy2 = Yy2;
  114.     pVw = Vw;    pHw = Hw;
  115.     pInfo = Info;
  116.     
  117.     Info = (struct txinfo_t *)WMGR_inf(nw);
  118.     pVg = Info->fontx + Info->linegap;
  119.     WMGR_cord(nw, &c);
  120.     Xx1 = c.x1;    Yy1 = c.y1;
  121.     Xx2 = c.x2;    Yy2 = c.y2;
  122.     
  123.     Cont_path(Info->name, (Xx2 - Xx1 - 122) / 8, (char *)str);
  124.     Draw_window((char *)str, Xx1, Yy1, Xx2, Yy2);
  125.     
  126.     Hw = (Xx2 - Xx1 - 31) / (Info->fontx / 2);
  127.     Vw = (Yy2 - Yy1 - 52 + Info->linegap) / pVg;
  128.     bm.tabm = Info->tabd;    bm.crm = Info->crd;
  129.     bm.fs = &Info->file;
  130.     bm.l = Info->col;
  131.     bm.r = Info->col + Hw - 1;
  132.     bm.tab = Info->tab;
  133.     MOS_disp(0);
  134.     for (i = 0; i < Vw && i + Info->line < Info->file.line; i++) {
  135.         bm.line = i + Info->line;
  136.         BMGR_String(&bm, str);
  137.         EGB_str3((char *)str, Xx1 + 8, Yy1 + 44 + i * pVg, PAL_MOJI, PAL_Back);
  138.     }
  139.     MOS_disp(1);
  140.     Draw_scrollV();
  141.     Draw_scrollH();
  142.     
  143.     Xx1 = pxx1;
  144.     Yy1 = pyy1;
  145.     Xx2 = pxx2;
  146.     Yy2 = pyy2;
  147.     Vw = pVw;
  148.     Hw = pHw;
  149.     Info = pInfo;
  150. }
  151.  
  152. /* テキスト・ウィンドウ メイン関数 x,y:マウス座標 */
  153. void TXW_main(int x, int y) {
  154.     int        wh, mx, my;
  155.     char    mb;
  156.     
  157.     switch (wh = Where(x, y)) {
  158.         case WH_TITLE:    SUB_move(x, y);        break;
  159.         case WH_CAN:    SUB_close();        break;
  160.         case WH_EXP:    SUB_enlarge(x, y);    break;
  161.         case WH_OPT1:    SUB_recall();        break;
  162.         case WH_OPT2:    SUB_dispchange();    break;
  163.         case WH_SCVRW:
  164.         case WH_SCVFF:
  165.         case WH_SCHRW:
  166.         case WH_SCHFF:    SUB_scya(wh - WH_SCVRW);    break;
  167.         case WH_BSCV:
  168.         case WH_BSCH:    SUB_scdr(WH_BSCH - wh, x, y);    break;
  169.         case WH_MOJI:    SUB_dragScroll();    break;
  170.         case WH_OTHER:    while (MOS_rdpos(&mb, &mx, &my), mb & 1);    break;
  171.     }
  172. }
  173.  
  174. static void SUB_dispchange(void) {
  175.     int        x, y, r;
  176.     
  177.     if (!Button(Xx2 - 46, Yy1 + 6, Xx2 - 27, Yy1 + 25))
  178.         return;
  179.     
  180.     x = Xx2 - 210 - Wx;    y = Yy1 + 32 - Wy;
  181.     if (x + 348 > 639)    x = 639 - 348;
  182.     if (y + 214 > 479)    y = 479 - 214;
  183.     TXW_close();
  184.     Xpage(0, Wx, Wy);
  185.     r = WIND_disp(0, Info, x, y);
  186.     Xpage(1, Wx, Wy);
  187.     EGB_rev(1, Xx2 - 46, Yy1 + 6, Xx2 - 27, Yy1 + 25);
  188.     if (r & 20) {
  189.         int        a;
  190.         
  191.         a = Info->lgcolw ? (Xx2 - Xx1 - 31) / (Info->fontx / 2) : Info->lgcol;
  192.         BMGR_change(a, Info->tab, &Info->file, &Info->line);
  193.         if (Info->col >= a)    Info->col = a - 1;
  194.         TXW_open(0, Wx, Wy);
  195.     } else
  196.         TXW_open(r & 8 ? 0 : 1, Wx, Wy);
  197. }
  198.  
  199. static void SUB_recall(void) {
  200.     struct RECT    w;
  201.     
  202.     if (!Button(Xx2 - 25, Yy1 + 6, Xx2 - 6, Yy1 + 25))
  203.         return;
  204.     
  205.     WMGR_pcord(-1, &w);
  206.     if (w.x1 < Wx || Wx + 639 < w.x2 || w.y1 < Wy + 40 || Wy + 479 < w.y2) {
  207.         int        a;
  208.         struct txinfo_t    *inf;
  209.         
  210.         a = WMGR_cWind();
  211.         WMGR_vanish(-2, Wx, Wy);
  212.         WMGR_change(a, &w);
  213.         inf = WMGR_inf(a);
  214.         Winsize_change_sub(inf, (w.x2 - w.x1 - 31) / (inf->fontx / 2));
  215.         TXW_draw(a);
  216.     } else {
  217.         WMGR_vanish(-1, Wx, Wy);
  218.         WMGR_change(-1, &w);
  219.         Winsize_change_sub(Info, (w.x2 - w.x1 - 31) / (Info->fontx / 2));
  220.         TXW_open(0, Wx, Wy);
  221.     }
  222. }
  223.  
  224. static void Winsize_change_sub(struct txinfo_t *inf, int b) {
  225.     if (inf->lgcolw)
  226.         BMGR_change(b, inf->tab, &inf->file, &inf->line);
  227.     else {
  228.         if (inf->col >= (inf->lgcolw ? b : inf->lgcol))
  229.             inf->col = (inf->lgcolw ? b : inf->lgcol) - 1;
  230.     }
  231. }
  232.  
  233. static void SUB_close(void) {
  234.     if (!Button(Xx1 + 6, Yy1 + 6, Xx1 + 25, Yy1 + 25))
  235.         return;
  236.     
  237.     free(Info->file.buf1);
  238.     free(Info->file.buf2);
  239.     WMGR_vanish(-1, Wx, Wy);
  240.     WMGR_unregi(-1);
  241. }
  242.  
  243. /* ウィンドウ移動関数   mx,my:マウス座標 */
  244. static void SUB_move(int mx, int my) {
  245.     struct RECT    w, s;
  246.     
  247.     w.x1 = Xx1;    w.y1 = Yy1;    w.x2 = Xx2;    w.y2 = Yy2;
  248.     s.x1 = Wx;    s.y1 = Wy + 40;    s.x2 = Wx + 639;    s.y2 = Wy + 479;
  249.     if (dragWindow(mx, my, &w, &s, Wx, Wy)) {
  250.         WMGR_vanish(-1, Wx, Wy);
  251.         WMGR_change(-1, &w);
  252.         TXW_open(0, Wx, Wy);
  253.     }
  254. }
  255.  
  256. /* マウス・カーソルの場所を識別する関数   x,y:マウス座標 */
  257. static int Where(int x, int y) {
  258.     int        i, wh = WH_OTHER;
  259.     const short    *p;
  260.     static const short    t[][9] = {
  261.         {26, -47, 5, 26, 0, 1, 0, 0, WH_TITLE},
  262.         {5, 26, 5, 26, 0, 0, 0, 0, WH_CAN},
  263.         {-21, -5, -21, -5, 1, 1, 1, 1, WH_EXP},
  264.         {-26, -5, 5, 26, 1, 1, 0, 0, WH_OPT1},
  265.         {-47, -26, 5, 26, 1, 1, 0, 0, WH_OPT2},
  266.         {-21, -5, 26, 42, 1, 1, 0, 0, WH_SCVRW},
  267.         {-21, -5, -37, -21, 1, 1, 1, 1, WH_SCVFF},
  268.         {5, 21, -21, -5, 0, 0, 1, 1, WH_SCHRW},
  269.         {-37, -21, -21, -5, 1, 1, 1, 1, WH_SCHFF},
  270.         {-21, -5, 42, -37, 1, 1, 0, 1, WH_BSCV},
  271.         {21, -37, -21, -5, 0, 1, 1, 1, WH_BSCH},
  272.         {8, -24, 28, -24, 0, 1, 0, 1, WH_MOJI}
  273.     };
  274.     
  275.     for (i = 0; i < 12; i++) {
  276.         p = t[i];
  277.         if (p[0] + (p[4] ? Xx2 : Xx1) < x && x < p[1] + (p[5] ? Xx2 : Xx1)
  278.             && p[2] + (p[6] ? Yy2 : Yy1) < y && y < p[3] + (p[7] ? Yy2 : Yy1)) {
  279.             wh = p[8];
  280.             break;
  281.         }
  282.     }
  283.     
  284.     return wh;
  285. }
  286.  
  287. int TXW_regi(const char *path, struct txinfo_t **tx, int x1, int x2) {
  288.     int        r;
  289.     struct filestore_t    fl;
  290.     
  291.     if ((*tx = malloc(sizeof(struct txinfo_t))) == NULL)
  292.         return -1;
  293.     
  294.     DSP_set(*tx);
  295.     strcpy((*tx)->name, path);
  296.     if (r = BMGR_set(path, (*tx)->lgcolw ? (x2 - x1 - 31) / ((*tx)->fontx / 2) : (*tx)->lgcol, (*tx)->tab, &fl)) {
  297.         free(*tx);
  298.         return r;
  299.     }
  300.     (*tx)->file = fl;
  301.     
  302.     return 0;
  303. }
  304.  
  305. static void SUB_enlarge(int x, int y) {
  306.     int        px, py, mx, my, a, b;
  307.     char    mb;
  308.     struct RECT    w;
  309.     
  310.     a = Xx2 - x;    b = Yy2 - y;
  311.     EGB_writeMode(EGB_work, 4);
  312.     MOS_horizon(Xx1 - a + 266, Wx - a + 639);
  313.     MOS_vertical(Yy1 - b + 95, Wy - b + 479);
  314.     
  315.     ICN_mos(4);
  316.     MOS_disp(0);
  317.     EGB_box(Xx1, Yy1, Xx2, Yy2, 15);
  318.     MOS_disp(1);
  319.     px = mx = x;    py = my = y;
  320.     do {
  321.         if (px == mx && py == my)
  322.             continue;
  323.         
  324.         MOS_disp(0);
  325.         EGB_box(Xx1, Yy1, px + a, py + b, 15);
  326.         EGB_box(Xx1, Yy1, mx + a, my + b, 15);
  327.         MOS_disp(1);
  328.         px = mx;    py = my;
  329.     } while (MOS_rdpos(&mb, &mx, &my), mb & 1);
  330.     MOS_disp(0);
  331.     EGB_box(Xx1, Yy1, px + a, py + b, 15);
  332.     MOS_disp(1);
  333.     EGB_writeMode(EGB_work, 0);
  334.     MOS_horizon(Wx, Wx + 639);
  335.     MOS_vertical(Wy, Wy + 479);
  336.     ICN_mos(0);
  337.     if (px == x && py == y)
  338.         return;
  339.     
  340.     if (x > px || y > py)
  341.         WMGR_vanish(-1, Wx, Wy);
  342.     w.x1 = Xx1;    w.y1 = Yy1;
  343.     w.x2 = px + a;    w.y2 = py + b;
  344.     WMGR_change(-1, &w);
  345.     Winsize_change_sub(Info, (px + a - Xx1 - 31) / (Info->fontx / 2));
  346.     TXW_open(0, Wx, Wy);
  347. }
  348.  
  349. static void Draw_window(char *t, int x1, int y1, int x2, int y2) {
  350.     struct opnwin_t    ot;
  351.     static const int    optw[] = {
  352.         2, 2
  353.     };
  354.     
  355.     ot.title = t;
  356.     ot.x1 = x1;
  357.     ot.y1 = y1;
  358.     ot.x2 = x2;
  359.     ot.y2 = y2;
  360.     ot.canb = 1;
  361.     ot.nopt = 2;
  362.     ot.wopt = optw;
  363.     ot.expb = 1;
  364.     ot.shdw = 0;
  365.     ot.ord = 1;
  366.     
  367.     MOS_disp(0);
  368.     drawWindow(&ot);
  369.     ICN_opt(0, x2 - 23, y1 + 8);
  370.     EGB_str2("★", x2 - 44, y1 + 23, PAL_Black);
  371.     MOS_disp(1);
  372. }
  373.  
  374. static void SUB_scya(int mode) {
  375.     int        lx, ly, flpush = 1, fllast;
  376.     int        mx, my;
  377.     char    mb;
  378.     
  379.     switch (mode) {
  380.         case 0:    lx = Xx2 - 20;    ly = Yy1 + 27;    break;
  381.         case 1:    lx = Xx2 - 20;    ly = Yy2 - 36;    break;
  382.         case 2:    lx = Xx1 + 6;    ly = Yy2 - 20;    break;
  383.         default:    lx = Xx2 - 36;    ly = Yy2 - 20;    break;
  384.     }
  385.     
  386.     TIMER_set(20);
  387.     EGB_rev(1, lx, ly, lx + 14, ly + 14);
  388.     if (fllast = SUB_scya_roll(mode))
  389.         SUB_scya_bar(mode);
  390.     
  391.     while (MOS_rdpos(&mb, &mx, &my), mb & 1) {
  392.         int        whres;
  393.         
  394.         whres = Where(mx, my) == mode + WH_SCVRW;
  395.         if (whres && !flpush || !whres && flpush) {
  396.             EGB_rev(1, lx, ly, lx + 14, ly + 14);
  397.             flpush = !flpush;
  398.             if (!flpush && !fllast)
  399.                 SUB_scya_bar(mode);
  400.         }
  401.         
  402.         if (flpush && TIMER() && !fllast) {
  403.             if (fllast = SUB_scya_roll(mode))
  404.                 SUB_scya_bar(mode);
  405.         }
  406.     }
  407.     
  408.     if (!fllast)
  409.         SUB_scya_bar(mode);
  410.     if (flpush)
  411.         EGB_rev(1, lx, ly, lx + 14, ly + 14);
  412. }
  413.  
  414. static int SUB_scya_roll(int mode) {
  415.     int        result;
  416.     
  417.     switch (mode) {
  418.         case 0:        result = SCROLL(0);        break;
  419.         case 1:        result = SCROLL(1);        break;
  420.         case 2:        result = ROL_horizon(-Hg);    break;
  421.         default:    result = ROL_horizon(Hg);    break;
  422.     }
  423.     
  424.     return result;
  425. }
  426.  
  427. static int SCROLL(int d) {
  428.     int        r = 0, i = 1, a, b = 0;
  429.     static const short    tab[] = {
  430.         1, 2, 4, 9, 20
  431.     };
  432.     
  433.     for (; i <= tab[Scspd]; i++) {
  434.         a = (10 * Vg * i / tab[Scspd] + 5) / 10;
  435.         if (r = ROL_vertical(d ? a - b : b - a))
  436.             break;
  437.         b = a;
  438.     }
  439.     
  440.     return r;
  441. }
  442.  
  443. static void SUB_scya_bar(int mode) {
  444.     switch (mode) {
  445.         case 0:    case 1:        Draw_scrollV();    break;
  446.         case 2:    default:    Draw_scrollH();    break;
  447.     }
  448. }
  449.  
  450. static void Draw_scrollV(void) {
  451.     int        xx, yy, bar, u, l;
  452.     struct sb_t    sb;
  453.     
  454.     xx = Xx2 - 20;
  455.     yy = Yy1 + 43;
  456.     
  457.     bar = Yy2 - Yy1 - 80;
  458.     sb.tl = Info->file.line;    sb.lpp = Vw;
  459.     sb.blen = bar;    sb.bml = 15;
  460.     SCRB_page(&sb, Info->line, &u, &l);
  461.     
  462.     MOS_disp(0);
  463.     if (u > 0)
  464.         EGB_boxf(xx, yy, xx + 14, yy + u - 1, 6, 6);
  465.     DrawButton(0, xx, yy + u, xx + 14, yy + l);
  466.     if (l < bar - 1)
  467.         EGB_boxf(xx, yy + l + 1, xx + 14, yy + bar - 1, 6, 6);
  468.     MOS_disp(1);
  469. }
  470.  
  471. static void Draw_scrollH(void) {
  472.     int        xx, yy, bar, u, l;
  473.     struct sb_t    sb;
  474.     
  475.     xx = Xx1 + 22;
  476.     yy = Yy2 - 20;
  477.     
  478.     bar = Xx2 - Xx1 - 59;
  479.     sb.tl = Info->lgcolw ? Hw : Info->lgcol;    sb.lpp = Hw;
  480.     sb.blen = bar;    sb.bml = 15;
  481.     SCRB_page(&sb, Info->col, &u, &l);
  482.     
  483.     MOS_disp(0);
  484.     if (u > 0)
  485.         EGB_boxf(xx, yy, xx + u - 1, yy + 14, 6, 6);
  486.     DrawButton(0, xx + u, yy, xx + l, yy + 14);
  487.     if (l < bar - 1)
  488.         EGB_boxf(xx + l + 1, yy, xx + bar - 1, yy + 14, 6, 6);
  489.     MOS_disp(1);
  490. }
  491.  
  492. void TXW_rollset(int a) {
  493.     Scspd = a;
  494. }
  495.  
  496. static void SUB_scdr(int mode, int mx, int my) {
  497.     int        flpush = 1, fldir = 0, t;
  498.     char    mb;
  499.     struct sb_t    sb;
  500.     
  501.     ICN_mos(3);
  502.     t = mode ? Yy1 + 43 : Xx1 + 22;
  503.     sb.tl = mode ? Info->file.line : Info->lgcolw ? Hw : Info->lgcol;
  504.     sb.lpp = mode ? Vw : Hw;
  505.     sb.blen = mode ? Yy2 - Yy1 - 79 : Xx2 - Xx1 - 58;    sb.bml = 15;
  506.     SCRB_bar(&sb, (mode ? my : mx) - t, mode ? &Info->line : &Info->col);
  507.     
  508.     mode ? Draw_scrollV() : Draw_scrollH();
  509.     ROL_init(Info, Xx1 + 8 - Wx, Yy1 + 29 - Wy, Xx1 + 7 + Hw * Hg - Wx, Yy1 + 28 + Vw * Vg - Info->linegap - Wy);
  510.     
  511.     while (MOS_rdpos(&mb, &mx, &my), mb & 1) {
  512.         int        a, b, f;
  513.         
  514.         if (Where(mx, my) != (mode ? WH_BSCV : WH_BSCH)) {
  515.             if (flpush) {
  516.                 fldir = 0;    flpush = 0;
  517.                 mode ? Draw_scrollV() : Draw_scrollH();
  518.             }
  519.             continue;
  520.         }
  521.         
  522.         flpush = 1;
  523.         SCRB_bar(&sb, (mode ? my : mx) - t, &a);
  524.         if ((b = mode ? Info->line : Info->col) > a) {
  525.             mode ? SCROLL(0) : ROL_horizon(-Hg);
  526.             f = 1;
  527.         } else if (b < a) {
  528.             mode ? SCROLL(1) : ROL_horizon(Hg);
  529.             f = -1;
  530.         } else
  531.             f = 0;
  532.         
  533.         if (fldir != f) {
  534.             fldir = f;
  535.             mode ? Draw_scrollV() : Draw_scrollH();
  536.         }
  537.     }
  538.     mode ? Draw_scrollV() : Draw_scrollH();
  539.     ICN_mos(0);
  540. }
  541.  
  542. static void SUB_dragScroll(void) {
  543.     int        mx, my, xx, yy;
  544.     int        w = 0, flsc = 1;
  545.     char    mb;
  546.     
  547.     ICN_mos(3);
  548.     MOS_motion(&xx, &yy);        /* Initialize */
  549.     do {
  550.         if (MOS_motion(&xx, &yy), !xx && !yy)
  551.             continue;
  552.         
  553.         if (abs(xx) > abs(yy)) {
  554.             if (flsc)
  555.                 SeigouV();
  556.             flsc = 0;
  557.             w = -xx;
  558.         } else {
  559.             if (!flsc)
  560.                 SeigouH();
  561.             flsc = 1;
  562.             w = -yy;
  563.         }
  564.         if (abs(w) > (flsc ? Vg : Hg)) {
  565.             w = flsc ? Vg : Hg;
  566.             if ((flsc ? -yy : -xx) < 0)
  567.                 w *= -1;
  568.         }
  569.         flsc ? ROL_vertical(w) : ROL_horizon(w);
  570.     } while (MOS_rdpos(&mb, &mx, &my), mb & 1 && Where(mx, my) == WH_MOJI);
  571.     ICN_mos(0);
  572.     
  573.     if (xx || yy) {
  574.         int        a;
  575.         
  576.         if (Where(mx, my) != WH_MOJI) {
  577.             do {
  578.                 a = flsc ? ROL_vertical(w) : ROL_horizon(w);
  579.             } while (MOS_rdpos(&mb, &mx, &my), mb & 1 && !a);
  580.             if (a) {
  581.                 Draw_scrollV();
  582.                 Draw_scrollH();
  583.                 while (MOS_rdpos(&mb, &mx, &my), mb & 1);
  584.             }
  585.         }
  586.         
  587.         do {
  588.             a = flsc ? ROL_vertical(w) : ROL_horizon(w);
  589.         } while (MOS_rdpos(&mb, &mx, &my), !(mb & 1) && !a);
  590.         if (Info->_line)
  591.             flsc ? ROL_vertical(w < 0 ? Info->_line : Vg - Info->_line) :
  592.                 ROL_horizon(w < 0 ? Info->_col : Hg - Info->_col);
  593.     } else {
  594.         flsc ? SeigouV() : SeigouH();
  595.     }
  596.     
  597.     Draw_scrollV();
  598.     Draw_scrollH();
  599. }
  600.  
  601. /* 垂直方向 整合 */
  602. static void SeigouV(void) {
  603.     if (0 < Info->_line && Info->_line < Vg / 2)
  604.         ROL_vertical(-Info->_line);
  605.     else if (Vg / 2 <= Info->_line && Info->_line < Vg)
  606.         ROL_vertical(Vg - Info->_line);
  607. }
  608.  
  609. /* 水平方向 整合 */
  610. static void SeigouH(void) {
  611.     if (0 < Info->_col && Info->_col < Hg / 2)
  612.         ROL_horizon(-Info->_col);
  613.     else if (Hg / 2 <= Info->_col && Info->_col < Hg)
  614.         ROL_horizon(Hg - Info->_col);
  615. }
  616.